//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.IO.Packaging;
using OpenLS.Core.Serialization;
using OpenLS.Spreadsheet.Expressions;
using OpenLS.Spreadsheet.Parsing;

namespace OpenLS.Spreadsheet
{
    public class Hyperlink : IOfficeXmlSerializable
    {
        #region IOfficeXmlSerializable Members

        void IOfficeXmlSerializable.ReadXml(ReadContext context)
        {
            
            using (ReadContext c = context.Read("hyperlink"))
            {
                string refValue = c.GetString("ref");
                string id = c.GetOptionalString(OfficeConstants.RelationshipNamespace + "id");
                if (id != null)
                {
                    PackageRelationship rel = c.Part.GetRelationship(id);
                    ExternalUri = rel.TargetUri;
                }
                var worksheet = c.GetData<Worksheet>();
                Source = worksheet[refValue];
                if (Source == null)
                {
                    Range r = worksheet.GetRange(refValue);
                    if (r == null)
                        r = worksheet.GetRange(refValue);
                    Source = r.TopLeftCell;
                }
                Source.Hyperlink = this;
                _location = c.GetOptionalString("location");
                _tooltip = c.GetOptionalString("tooltip");
                _display = c.GetOptionalString("display");
            }
        }

        void IOfficeXmlSerializable.WriteXml(WriteContext context)
        {
            using (WriteContext c = context.Write("hyperlink"))
            {
                string Ref;
                Ref = Source.RowSpan * Source.ColumnSpan == 1 ? Source.Label : Source.ToRange().Address.Label;
                c.SetString("ref", Ref);
                if (ExternalUri != null)
                {
                    PackageRelationship rel = context.Part.CreateRelationship(ExternalUri, TargetMode.External, OfficeConstants.HyperlinkRelationshipType);
                    c.SetString(OfficeConstants.RelationshipNamespace + "id", rel.Id);
                }
                if (Target != null)
                    Location = Target.FullLabel;
                c.SetOptionalString("location", _location);
                c.SetOptionalString("tooltip", _tooltip);
                c.SetOptionalString("display", _display);
            }
        }

        #endregion

        public Uri ExternalUri { get; set; }


        internal int Id { get; set; }

        private string _location;

        string Location
        {
            get { return _location; }
            set { _location = value; }
        }
        [Obsolete("Use TargetCell instead")]
        public Cell Target
        {
            get { return TargetCell; }
            set { TargetCell = value; }
        }

        public Cell TargetCell
        {
            get
            {
                if (Location == null)
                    return null;
                var parser = new ExpressionParser(this.Source.Worksheet, this.Source, LocalizationMode.NonLocalized,
                                                             CellReferenceMode.Static);
                try
                {
                    string s = Location.Trim();
                    if (!s.StartsWith("="))
                        s = "=" + s;
                    var expression = parser.Expression(s);
                    if (expression is CellReferenceExpression)
                    {
                        var cr = (CellReferenceExpression) expression;
                        return cr.Cell(new CellEvaluationContext(Source));
                    }
                    return null;
                }
                catch (Exception)
                {
                    return null;
                }
            }
            set
            {
                Location = value.FullLabel;

            }
        }

        public Cell Source { get; set; }

        private string _tooltip;

        public string Tooltip
        {
            get { return _tooltip; }
            set { _tooltip = value; }
        }
        private string _display;

        public string Display
        {
            get { return _display; }
            set { _display = value; }
        }





    }
}
